package com.kll.carolinehmibiz.net

import android.content.Context
import com.kll.carolinehmibiz.base.net.UrlConfig
import com.kll.carolinehmibiz.base.net.bean.BaseHttpResult
import com.kll.carolinehmibiz.base.net.rx.NetObserver
import com.kll.carolinehmibiz.base.net.rx.RxBase
import com.kll.carolinehmibiz.net.bean.*
import com.kll.carolinehmibiz.net.listener.DownloadListener
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit


/**
 * ====================================================
 *
 * 后台api访问工具类
 *
 * Created by Ziliang Cai on 2021/12/6 21:27
 * <a href="mailto:752577456@qq.com">Contact me</a>
 * ====================================================
 */
class CarolineNetHelper: RxBase {

    private var mContext: Context? = null

    companion object {

        private var mInstance: CarolineNetHelper? = null
        private var carolineNetApi: CarolineNetApi? = null

        @Synchronized
        fun getInstance(context: Context): CarolineNetHelper {
            if(mInstance == null) {
                mInstance = CarolineNetHelper(context)
            }

            return mInstance!!
        }
    }

    constructor(context: Context) {

        mContext = context.applicationContext

        // 打印日志
        var retrofix = getRetrofix( null)

        carolineNetApi = retrofix.create(CarolineNetApi::class.java)
    }

    /**
     * 构建下载
     */
    private fun getDownloadApi(downloadInterceptor: DownloadInterceptor): CarolineFileNetApi{
        // 打印日志
        var retrofix = getRetrofix( downloadInterceptor)

        return retrofix.create(CarolineFileNetApi::class.java)
    }

    private fun getRetrofix(downloadInterceptor: DownloadInterceptor?): Retrofit {

        //配置RetrofitUrlManager用于URL管理及切换

        var httpClientBuilder = RetrofixUrlManager.getInstance(mContext!!).with(OkHttpClient.Builder())
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) // 添加日志拦截器
            .connectTimeout(12,  TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)

        if(downloadInterceptor != null) {
            httpClientBuilder.addInterceptor(downloadInterceptor)
        }

        // 打印日志
        var retrofix = Retrofit.Builder()
            .baseUrl(UrlConfig.URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(httpClientBuilder.build())
            .build()

        return retrofix

    }

    /**
     * 查询设备是否激活
     */
    fun getDeviceActiveStatus(observer: NetObserver<BaseHttpResult<GetActiveStatusResponse>>) {
        var observable = carolineNetApi?.getDeviceActiveStatus(1)

        toSubscribe(observable, observer)
    }

    /**
     * 激活并登录设备
     */
    fun activeDevice(mobile: String, code: String, observer: NetObserver<BaseHttpResult<LoginResponse>>) {
        var observable = carolineNetApi?.activeDevice(mobile, code, 1)
        toSubscribe(observable, observer)
    }

    /**
     * 获取系统菜单(全部)
     *
     */
    fun getSystemAllMenus(observer: NetObserver<BaseHttpResult<ArrayList<GetSystemMenuResponse>>>) {
        var observable = carolineNetApi?.getSystemMenu("home", 0, 0, null)

        toSubscribe(observable, observer)
    }

    fun getSystemMenuDetail(menuId: Int, observer: NetObserver<BaseHttpResult<ArrayList<GetSystemMenuDetailResponse>>>) {
        var observable = carolineNetApi?.getSystemMenuDetail(menuId)

        toSubscribe(observable, observer)
    }

    /**
     * 获取验证码
     *
     * @param mobile 手机号
     */
    fun getVerifyCode(observer: NetObserver<BaseHttpResult<ArrayList<EmptyResponse>>>, mobile: String){

        var observable =  carolineNetApi?.getVerifiCode("26945134", mobile)

        toSubscribe(observable, observer)
    }

    /**
     * 上传图片
     * @param url
     * @param key
     * @param token
     */
    fun uploadImage(url: String, key: String,  token: String, file: File, observer: NetObserver<BaseHttpResult<ArrayList<UploadFileResponse>?>>){

        // file
        var requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file)
//        var filePart = MultipartBody.Part.createFormData("file", file.name, requestFile)

        // body
        var requestBody = MultipartBody.Builder()
            .setType(MediaType.parse("multipart/form-data"))
            .addFormDataPart("key", key)
            .addFormDataPart("token", token)
            .addFormDataPart("file", file.name, requestFile)
            .build()

        var observable = carolineNetApi?.uploadFile(url, requestBody)

        toSubscribe(observable, observer)

    }

    /**
     * 下载文件
     */
    fun downloadFile(url: String, downloadListener: DownloadListener, callback: Observer<ResponseBody>) {

        getDownloadApi(DownloadInterceptor(downloadListener)).downloadFile(url)
            ?.subscribeOn(Schedulers.io())
            ?.unsubscribeOn(Schedulers.io())
            ?.observeOn(AndroidSchedulers.mainThread())
            ?.subscribe(callback);

//        carolineNetApi?.downloadFile(url)
//            ?.subscribeOn(Schedulers.io())
//            ?.unsubscribeOn(Schedulers.io())
//            ?.observeOn(AndroidSchedulers.mainThread())
//            ?.subscribe(callback);
    }

    /**
     * 登录
     * @param verifyCode 验证码
     * @param mobile 手机号
     */
    fun login(observer: NetObserver<BaseHttpResult<LoginResponse>>, verifyCode: String, mobile: String) {

        var observable = carolineNetApi?.login(verifyCode, mobile)

        toSubscribe(observable, observer)
    }

    /**
     * 重置密码
     */
    fun resetPwd(observer: NetObserver<BaseHttpResult<EmptyResponse>>, mobile: String, verifyCode: String, pwd: String) {
        var observable = carolineNetApi?.resetPwd(verifyCode, mobile, pwd, pwd)
        toSubscribe(observable, observer)
    }

    /**
     * 获取验证码
     *
     * @param mobile 手机号
     */
    fun register(observer: NetObserver<BaseHttpResult<Boolean>>, sn: String, mobile: String, code: String){

        var observable =  carolineNetApi?.register(3,  sn, mobile, code)

        toSubscribe(observable, observer)
    }

    /**
     * 获取上传信息token
     */
    fun getUploadInfo(observer: NetObserver<BaseHttpResult<GetUploadInfoReponse?>>){
        var observable = carolineNetApi?.getUploadInfo()

        toSubscribe(observable, observer)
    }

    /**
     * 获取用户信息
     */
    fun getUserInfo(observer: NetObserver<BaseHttpResult<GetUserInfoResponse?>>) {
        var observable = carolineNetApi?.getUserInfo()

        toSubscribe(observable, observer)
    }

    /**
     * 修改用户信息
     */
    fun editUserInfo(userInfo: GetUserInfoResponse, observer: NetObserver<BaseHttpResult<EmptyResponse?>>) {

        var observable = carolineNetApi?.editUserInfo(userInfo.username, userInfo.head_pic,  userInfo.sex, userInfo.birthday)

        toSubscribe(observable, observer)
    }

    /**
     * 获取设置信息
     */
    fun getSetting(code: String, observer: NetObserver<BaseHttpResult<GetSettingResponse>>) {
        var observable = carolineNetApi?.getSetting("system_info", "code")

        toSubscribe(observable, observer)
    }

    /**
     * 获取分配客服
     *
     * @param type 客服类型 1：默认客服，2：基因检测，3：全息影像筛查，4：饮食检测，5：失忆预防检测，6：中医检测，7；睡眠呼吸检测，8；中医康复，9；饮食康复，10；运动健康，11；再生医学康复，12；睡眠障碍康复，13；自助问诊
     */
    fun getAssignCustomerService(type: Int, observer: NetObserver<BaseHttpResult<GetAssignCustomerServiceResponse?>>) {
        var observable = carolineNetApi?.getAssignCustomerService(type)

        toSubscribe(observable, observer)
    }

    /**
     * 生成userSig
     *
     * @param userId 用户 ID
     * @param expire 签名过期时间
     */
    fun createUserSig(userId: String, expire: Long, observer: NetObserver<BaseHttpResult<GetCreateUserSig>>) {
        var observable = carolineNetApi?.createUserSig(userId, expire)

        toSubscribe(observable, observer)
    }

    /**
     * 获取IM房间号
     *
     */
    fun getRoomId(callUserId: String, observer: NetObserver<BaseHttpResult<GetRoomIdResponse>>) {
        var observable = carolineNetApi?.getRoomId(callUserId)

        toSubscribe(observable, observer)
    }

    /**
     * 添加家人
     *
     * @param mobile 手机号
     * @param avatar 头像url
     * @param firstName 姓氏
     * @param lastName 名
     * @param remark 备注
     */
    fun addFamily(mobile: String, avatar: String, firstName: String, lastName: String, remark: String, observer: NetObserver<BaseHttpResult<EmptyResponse?>>){
        var observable = carolineNetApi?.addFamily(mobile, avatar, firstName, lastName, remark)

        toSubscribe(observable, observer)
    }

    /**
     * 编辑家人
     *
     * @param familyId 家人ID
     * @param mobile 手机号
     * @param avatar 头像url
     * @param firstName 姓氏
     * @param lastName 名
     * @param remark 备注
     *
     */
    fun editFamily(
        familyId: Int, mobile: String, avatar: String,
        firstName: String, lastName: String, remark: String, observer: NetObserver<BaseHttpResult<EmptyResponse?>>
    ) {
        var observable = carolineNetApi?.editFamily(familyId, mobile, avatar, firstName, lastName, remark)

        toSubscribe(observable, observer)
    }

    /**
     * 获取家人列表
     */
    fun getFamily(observer: NetObserver<BaseHttpResult<ArrayList<GetFamilyResponse>?>>) {
        var observable = carolineNetApi?.getFamily()

        toSubscribe(observable, observer)
    }

    /**
     * 获取用户活跃的腾讯云IM用户id
     */
    fun getTencentId(tencentUserId: String, observer: NetObserver<BaseHttpResult<GetTencentUserIdResponse>>) {
        var observable = carolineNetApi?.getTencentId(tencentUserId)

        toSubscribe(observable, observer)
    }

    /**
     * 删除家人
     *
     * @param familyId 家人ID
     */
    fun delFamily(familyId: Int, observer: NetObserver<BaseHttpResult<String?>>) {
        var observable = carolineNetApi?.delFamily(familyId)

        toSubscribe(observable, observer)
    }

    /**
     * 获取广告
     */
    fun getAds(code: String, observer: NetObserver<BaseHttpResult<GetAdsResponse?>>) {
        var observable = carolineNetApi?.getAds(code)

        toSubscribe(observable, observer)
    }

    /**
     * 获取疾病列表
     * @param maxId 上一次获取到的max_id
     */
    fun getDiseases(maxId: Int?, observer: NetObserver<BaseHttpResult<GetDiseaseResponse?>>) {
        var observable = carolineNetApi?.getDiseases(maxId)

        toSubscribe(observable, observer)
    }

    fun getCalllog(maxId: Int?, observer: NetObserver<BaseHttpResult<GetCalllogResponse>>) {
        var observable = carolineNetApi?.getCallLog(maxId)

        toSubscribe(observable, observer)
    }

    /**
     * 获取地址
     * @param regionId 地区ID
     */
    fun getRegion(regionId: Int, observer: NetObserver<BaseHttpResult<ArrayList<GetRegionResponse>>>) {
        var observable = carolineNetApi?.getRegion(regionId)

        toSubscribe(observable, observer)
    }

    /**
     * 获取收货地址
     */
    fun getAddress(observer: NetObserver<BaseHttpResult<List<GetAddressResponse?>>>) {
        var observable = carolineNetApi?.getAddress()
        toSubscribe(observable, observer)
    }

    /**
     * 添加地址
     */
    fun addAddress(consignee: String, regionList: ArrayList<Int>, address: String, mobile: String, isDefault: Int, observer: NetObserver<BaseHttpResult<GetAddressResponse>>) {
        val getAddressResponse = GetAddressResponse()
        getAddressResponse.consignee = consignee
        getAddressResponse.region_list = regionList
        getAddressResponse.address = address
        getAddressResponse.mobile = mobile
        getAddressResponse.is_default = isDefault
        var observable = carolineNetApi?.addAddress(getAddressResponse)

        toSubscribe(observable, observer)
    }

    /**
     * 编辑地址
     */
    fun editAddress(userAddressId: Int, consignee: String, regionList: ArrayList<Int>, region: String, address: String, mobile: String,
                   isDefault: Int, observer: NetObserver<BaseHttpResult<GetAddressResponse>>) {
        val getAddressResponse = GetAddressResponse()
        getAddressResponse.user_address_id = userAddressId
        getAddressResponse.consignee = consignee
        getAddressResponse.country = 1
        getAddressResponse.region_list = regionList
        getAddressResponse.region = region
        getAddressResponse.address = address
        getAddressResponse.zipcode = ""
        getAddressResponse.mobile = mobile
        getAddressResponse.is_default = isDefault
        var observable = carolineNetApi?.editAddress(getAddressResponse)

        toSubscribe(observable, observer)
    }

    /**
     * 删除地址
     */
    fun delAddress(userAddressId: IntArray, observer: NetObserver<BaseHttpResult<EmptyResponse>>) {
        val userAddressIds = UserAddressId()
        userAddressIds.user_address_id = userAddressId
        var observable = carolineNetApi?.delAddress(userAddressIds)

        toSubscribe(observable, observer)
    }

    /**
     * 获取最新版本信息
     */
    fun getAppNewlyVersion(observer: NetObserver<BaseHttpResult<GetAppNewlyVersionResponse?>>) {
        var observable = carolineNetApi?.getAppNewlyVersion()

        toSubscribe(observable, observer)
    }

    /**
     * 获取每日健康指数
     */
    fun getDaily(sday: String, observer: NetObserver<BaseHttpResult<ArrayList<DailyResponse>>>) {
        val date = Date()
        date.sday = sday
        var observable = carolineNetApi?.getDaily(date)

        toSubscribe(observable, observer)
    }

    /**
     * 刷新token
     */
    fun refreshToken(observer: NetObserver<BaseHttpResult<RefreshTokenResponse>>) {
        var observable = carolineNetApi?.refreshToken()

        toSubscribe(observable, observer)
    }

    /**
     * 图片列表
     */
    fun getAlbum(maxId: Int?, observer: NetObserver<BaseHttpResult<GetPhotoAlbumResponse>>) {
        var observable = carolineNetApi?.getAlbum(maxId)

        toSubscribe(observable, observer)
    }

    /**
     * 添加图片
     */
    fun addPhoto(list: ArrayList<AddPhoto.Photo>, observer: NetObserver<BaseHttpResult<EmptyResponse>>) {
        val addPhoto = AddPhoto()
        addPhoto.list = list
        var observable = carolineNetApi?.addPhoto(addPhoto)

        toSubscribe(observable, observer)
    }

    /**
     * 删除图片
     */
    fun delPhoto(list: ArrayList<Int>, observer: NetObserver<BaseHttpResult<EmptyResponse>>) {
        val delPhoto = DelPhoto()
        delPhoto.list = list
        var observable = carolineNetApi?.delPhoto(delPhoto)

        toSubscribe(observable, observer)
    }

}